package com.agileai.esb.smc.controller.sysres;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.esb.component.manager.ServiceConsumerManager;
import com.agileai.esb.component.manager.ServiceProducerManager;
import com.agileai.esb.component.manager.WebServiceProxyManager;
import com.agileai.esb.smc.bizmoduler.sysres.WsProxyManage;
import com.agileai.esb.smc.domain.User;
import com.agileai.hotweb.controller.core.StandardEditHandler;
import com.agileai.hotweb.domain.FormSelectFactory;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.DateUtil;
import com.agileai.util.StringUtil;

public class WsProxyManageEditHandler
        extends StandardEditHandler {
	public static final String CREATE = "_create_";
	public static final String Y = "Y";
	public static final String N = "N";
    public WsProxyManageEditHandler() {
        super();
        this.listHandlerClass = WsProxyManageListHandler.class;
        this.serviceId = buildServiceId(WsProxyManage.class);
    }
    
    public ViewRenderer prepareDisplay(DataParam param) {
		String operaType = param.get(OperaType.KEY);
		
		User user = (User)this.getUser();
		String userName = user.getUserName();
		String userId = user.getId();
		
		int wsTimeout = 30;
		String date = DateUtil.getDateByType(DateUtil.YYMMDDHHMISS_HORIZONTAL, new Date());
		
		if (isReqRecordOperaType(operaType)){
			param.put("showWsProxy", Y);
			DataRow record = getService().getRecord(param);
			this.setAttributes(record);	
			if(StringUtil.isNullOrEmpty(record.stringValue("UPDATE_TIME"))){
				param.put("UPDATE_TIME",date);
				this.setAttribute("UPDATE_TIME", date);
			}
			if(StringUtil.isNullOrEmpty(record.stringValue("UPDATE_USER"))){
				param.put("UPDATE_USER", userId);
				this.setAttribute("UPDATE_USER", userId);
				this.setAttribute("UPDATE_USER_NAME", userName);
			}
			if(StringUtil.isNullOrEmpty(record.stringValue("WS_TIMEOUT"))){
				param.put("WS_TIMEOUT", wsTimeout);
				this.setAttribute("WS_TIMEOUT", wsTimeout);
			}
			String appName = record.getString("APP_NAME");
			String serviceName = record.getString("WS_NAME");
			List<DataRow> producerRecords = ServiceProducerManager.instance(appName).getProduceAppRecords(serviceName);
			List<DataRow> consumerRecords = ServiceConsumerManager.instance(appName).getConsumeAppRecords(serviceName);
			
			String procuderName = this.buildNames(producerRecords);
			String consumerName = this.buildNames(consumerRecords);
			this.setAttribute("PRODUCER_NAME", procuderName);
			this.setAttribute("CONSUMER_NAME", consumerName);
			
			this.setAttribute("showUpdateUser", true);
		}else if(OperaType.CREATE.equals(operaType)){
			param.put("CREATE_TIME",date);
			param.put("CREATE_USER", userId);
			param.put("WS_TIMEOUT", wsTimeout);
			this.setAttribute("CREATE_TIME", date);
			this.setAttribute("CREATE_USER", userId);
			this.setAttribute("CREATE_USER_NAME", userName);
			this.setAttribute("showUpdateUser", false);
			this.setAttribute("WS_TIMEOUT", wsTimeout);
		}else if(CREATE.equals(operaType)){
			DataRow record = getService().getRecord(param);
			this.setAttributes(record);	
			
			if(StringUtil.isNullOrEmpty(record.stringValue("WS_TIMEOUT"))){
				param.put("WS_TIMEOUT", wsTimeout);
				this.setAttribute("WS_TIMEOUT", wsTimeout);
			}
		}
		String showWsProxy = param.get("showWsProxy");
		if(StringUtil.isNotNullNotEmpty(showWsProxy)){
			this.setAttribute("showWsProxy", showWsProxy);
		}else{
			this.setAttribute("showWsProxy", N);
		}
		String appId = param.get("APP_ID");
		this.setAttribute("APP_ID", appId);
		this.setOperaType(operaType);
		processPageAttributes(param);
		return new LocalRenderer(getPage());
	}

    private String buildNames(List<DataRow> producerRecords){
    	String result = "";
    	StringBuffer sb = new StringBuffer();
    	for (int i=0;i < producerRecords.size();i++){
    		DataRow row = producerRecords.get(i);
    		String sysInfoCode = row.getString("SYSINFO_CODE");
    		sb.append(",").append(sysInfoCode);
    	}
    	if (sb.length() > 1){
    		result = sb.substring(1);
    	}
    	return result;
    }
    
    protected void processPageAttributes(DataParam param) {
    	setAttribute("WS_STATE",
                FormSelectFactory.create("BOOL_DEFINE")
                                 .addSelectedValue(getOperaAttributeValue("WS_STATE",
                                                                          "Y")));
        setAttribute("ENABLE_AUTH",
                     FormSelectFactory.create("ENABLE_AUTH")
                                      .addSelectedValue(getOperaAttributeValue("ENABLE_AUTH",
                                                                               "N")));
        setAttribute("ENABLE_BIZLOG",
                     FormSelectFactory.create("BOOL_DEFINE")
                                      .addSelectedValue(getOperaAttributeValue("ENABLE_BIZLOG",
                                                                               "N")));
    }
    
    public ViewRenderer doSaveAction(DataParam param){
		String operateType = param.get(OperaType.KEY);
		if (OperaType.CREATE.equals(operateType)){
			getService().createRecord(param);	
			param.put(OperaType.KEY, CREATE);
		}
		else if (OperaType.UPDATE.equals(operateType)){
			User user = (User)this.getUser();
			param.put("UPDATE_USER",user.getId());
			param.put("UPDATE_TIME",new Date());
			getService().updateRecord(param);	
		}
		String appId = param.get("APP_ID");
		WsProxyManage service = this.lookupService(WsProxyManage.class);
		DataRow record = service.getAppRecord(appId);
		String appName = record.getString("APP_NAME");
		String wsName = param.get("WS_NAME");
		WebServiceProxyManager.instance(appName).refreshProxyModel(wsName);
		param.put("showWsProxy", Y);
		
		return prepareDisplay(param);
	}
    
    @SuppressWarnings("rawtypes")
	public ViewRenderer doAnalysisWsName8AccessuriAction(DataParam param){
		String responseText = FAIL;
		List<String> wsNameList = new ArrayList<String>(); 
		List<String> accessUriList = new ArrayList<String>(); 
		String wsdlURL = param.get("WS_ADDRESS");		
		WSDLFactory factory;
		try {
			factory = WSDLFactory.newInstance();
			WSDLReader reader=factory.newWSDLReader();  
			reader.setFeature("javax.wsdl.verbose",true);  
			reader.setFeature("javax.wsdl.importDocuments",true);  
			Definition def = reader.readWSDL(wsdlURL);  
			Map serviceMap = def.getServices();
			Iterator serviceIter = serviceMap.keySet().iterator();
			while (serviceIter.hasNext()){
				Object key = serviceIter.next();
				Service service = (Service)serviceMap.get(key);
				String servicName = service.getQName().getLocalPart();
				wsNameList.add(servicName);
				Map portMap = service.getPorts();
				Iterator portIter = portMap.keySet().iterator();
				while (portIter.hasNext()){
					Object portKey = portIter.next();
					Port port = (Port)portMap.get(portKey);
					List elements = port.getExtensibilityElements();
					
					for (int i=0;i < elements.size();i++){
						Object element = elements.get(i);
						if (element instanceof SOAPAddress){
							SOAPAddress soapAddress = (SOAPAddress)element;
							String locationURI = soapAddress.getLocationURI();
							accessUriList.add(locationURI);
						}
						
					}
				}
			}
			if(wsNameList.size() > 0 && accessUriList.size() > 0){
				responseText = this.bulidJSONObject(wsNameList,accessUriList);
			}
		} catch (WSDLException e) {
			e.printStackTrace();
		}  
		return new AjaxRenderer(responseText);
	}
    
    public String bulidJSONObject(List<String> wsNameList,List<String> accessUriList){
    	String responseText = "";
    	String servicName = wsNameList.get(0);
    	String locationURI = accessUriList.get(0);
    	JSONObject jsonObject = new JSONObject();
    	try {
			jsonObject.put("servicName", servicName);
			jsonObject.put("locationURI", locationURI);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		responseText = jsonObject.toString();
    	return responseText;
    }

    protected WsProxyManage getService() {
        return (WsProxyManage) this.lookupService(this.getServiceId());
    }
}
